﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace ServiceLayer.Forms
{
    /// <summary>
    /// Форма параметров соединения
    /// </summary>
    public partial class FormConnectionParams : Form
    {
        private XmlDocument xmldoc = null;

        private byte[] GetKey(uint length)
        {
            byte[] Key = new byte[length < 2 ? 2 : length];
            Key[0] = 3;
            Key[1] = 5;
            for (int i = 2; i < length; i++)
                Key[i] = (byte) (Key[i - 1] + Key[i - 2]);
            return Key;
        }

        private String DecodePassword(String IncodePassword)
        {
            byte[] bytes = Encoding.Default.GetBytes(IncodePassword);
            byte[] Key = GetKey((uint) IncodePassword.Length);
            for (int i = 0; i < bytes.Length; i++)
                bytes[i] = (byte) (bytes[i] ^ Key[i]);
            return Encoding.Default.GetString(bytes);
        }

        private String IncodePassword(String Password)
        {
            return DecodePassword(Password);
        }

        /// <summary>
        /// Конструктор по умолчанию
        /// </summary>
        public FormConnectionParams()
        {
            InitializeComponent();
        }
        /// <summary>
        /// Номер порта подключения
        /// </summary>
        public Int32 Port
        {
            get
            {
                return (Int32) numPort.Value;
            }
        }
        /// <summary>
        /// Строка возвращает имя сервера базы данных, которое было установлено пользователем
        /// </summary>
        public String Server
        {
            get
            {
                return cbServer.Text.Trim();
            }
        }
        /// <summary>
        /// Возвращает имя базы данных
        /// </summary>
        public String DataBase
        {
            get
            {
                return cbDataBase.Text.Trim();
            }
        }
        /// <summary>
        /// Имя пользователя от имени которого производиться подключение
        /// </summary>
        public String User
        {
            get
            {
                return cbUser.Text.Trim();
            }
        }
        /// <summary>
        /// Пароль пользователя, для подключения к базе
        /// </summary>
        public String Password
        {
            get
            {
                return tbPassword.Text;
            }
        }
        /// <summary>
        /// Загрузка данных в форму
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormConnectionParams_Load(object sender, EventArgs e)
        {
            xmldoc = new XmlDocument();
            xmldoc.Load("connect.xml");
            //Загружаем список серверов
            cbServer.Items.Clear();
            foreach (XmlNode node in xmldoc.SelectNodes("//connect/servers/server"))
            {
                if (node != null)
                    cbServer.Items.Add(node.InnerText);
            }
            cbServer.Text = xmldoc.SelectSingleNode("//connect/servers").Attributes["last"].InnerText;
            //Загружаем номер порта
            numPort.Value = Convert.ToUInt32(xmldoc.SelectSingleNode("//connect/port").InnerText);
            //Загружаем список баз данных
            cbDataBase.Items.Clear();
            foreach (XmlNode node in xmldoc.SelectNodes("//connect/databases/database"))
            {
                if (node != null)
                    cbDataBase.Items.Add(node.InnerText);
            }
            cbDataBase.Text = xmldoc.SelectSingleNode("//connect/databases").Attributes["last"].InnerText;
            //Загружаем список пользователей
            cbUser.Items.Clear();
            foreach (XmlNode node in xmldoc.SelectNodes("//connect/users/user"))
            {
                if (node != null)
                    cbUser.Items.Add(node.InnerText);
            }
            cbUser.Text = xmldoc.SelectSingleNode("//connect/users").Attributes["last"].InnerText;
            //Загружаем ранее сохранённый пароль
            if (xmldoc.SelectSingleNode("//connect/password").Attributes["save"].InnerText == "yes")
            {
                tbPassword.Text = DecodePassword(xmldoc.SelectSingleNode("//connect/password").InnerText.Trim());
                SavePassword.Checked = true;
            }
            else
                SavePassword.Checked = false;
            
        }
        private void FormConnectionParams_FormClosed(object sender, FormClosedEventArgs e)
        {
            //Сохраняем пароль
            xmldoc.SelectSingleNode("//connect/servers").Attributes["last"].InnerText = Server;
            if (!cbServer.Items.Contains(cbServer.Text.Trim()))
                xmldoc.SelectSingleNode("//connect/servers").AppendChild(xmldoc.CreateNode("element", "server", Server));
            
            //Запоминаем вводимый порт
            xmldoc.SelectSingleNode("//connect/port").InnerText = numPort.Value.ToString();
            
            //Запоминаем имя базы данных
            xmldoc.SelectSingleNode("//connect/databases").Attributes["last"].InnerText = DataBase;
            if (!cbServer.Items.Contains(cbServer.Text.Trim()))
                xmldoc.SelectSingleNode("//connect/databases").AppendChild(xmldoc.CreateNode("element", "database", DataBase));

            //Запоминаем имя пользователя
            xmldoc.SelectSingleNode("//connect/users").Attributes["last"].InnerText = User;
            if (!cbServer.Items.Contains(cbServer.Text.Trim()))
                xmldoc.SelectSingleNode("//connect/users").AppendChild(xmldoc.CreateNode("element", "user", DataBase));

            //Сохраняем пароль
            xmldoc.SelectSingleNode("//connect/password").Attributes["save"].InnerText = SavePassword.Checked ? "yes" : "no";
            if (SavePassword.Checked)
                xmldoc.SelectSingleNode("//connect/password").InnerText = IncodePassword(tbPassword.Text);
            else
                xmldoc.SelectSingleNode("//connect/password").InnerText = "";

            xmldoc.Save("connect.xml");
        }

        private void SavePassword_CheckedChanged(object sender, EventArgs e)
        {
            //if (SavePassword.Checked)
            //    MessageBox.Show("Установка данного значения резко снижает уровень безопасности при работе с БД!", 
            //                    "Внимание!!!",
            //                    MessageBoxButtons.OK,
            //                    MessageBoxIcon.Warning);
        }
    }
}
